<html>
<head><meta charset="utf-8"><title>Meaning of lifetimes · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Meaning.20of.20lifetimes.html">Meaning of lifetimes</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="231502932"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Meaning%20of%20lifetimes/near/231502932" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christian Mazakas <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Meaning.20of.20lifetimes.html#231502932">(Mar 23 2021 at 16:44)</a>:</h4>
<p>Just a quick question.</p>
<p>Let's say we have a <code>let x : &amp;'a T  = ...</code>.</p>
<p>Is it correct to say that semantically, <code>x</code> is a pointer to an object within its lifetime denoted as <code>'a</code>?</p>
<p>i.e. the <code>'a</code> refers specifically to the object living at the address <code>x</code></p>
<p>Someone on discord said this wasn't a correct interpretation which is why I'm asking here</p>



<a name="231503493"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Meaning%20of%20lifetimes/near/231503493" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Meaning.20of.20lifetimes.html#231503493">(Mar 23 2021 at 16:47)</a>:</h4>
<p><code>'a</code> can be shorter than the lifetime of the object</p>



<a name="231503618"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Meaning%20of%20lifetimes/near/231503618" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Meaning.20of.20lifetimes.html#231503618">(Mar 23 2021 at 16:48)</a>:</h4>
<p>A lifetime <code>'a</code> in a reference means that the referenced object is guaranteed to live <em>at least</em> as long as the lifetime <code>'a</code></p>



<a name="231503736"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Meaning%20of%20lifetimes/near/231503736" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christian Mazakas <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Meaning.20of.20lifetimes.html#231503736">(Mar 23 2021 at 16:49)</a>:</h4>
<p>Heh, quick resonse!</p>
<p>What does it look like to create that kind of reference?</p>
<div class="codehilite"><pre><span></span><code>let v = 1337;
let x = &amp;v;
// x is `&amp;&#39;a i32` where &#39;a = full lifetime of `v`
</code></pre></div>
<p>How do we create a reference with a shorter lifetime?</p>



<a name="231504116"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Meaning%20of%20lifetimes/near/231504116" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hyd-dev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Meaning.20of.20lifetimes.html#231504116">(Mar 23 2021 at 16:51)</a>:</h4>
<p>Like this?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="p">(</span><span class="n">x</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">a</span> <span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">y</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">a</span> <span class="kt">i32</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">a</span> <span class="kt">i32</span> <span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">y</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w">        </span><span class="n">foo</span><span class="p">(</span><span class="o">&amp;</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">y</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="231504414"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Meaning%20of%20lifetimes/near/231504414" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Christian Mazakas <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Meaning.20of.20lifetimes.html#231504414">(Mar 23 2021 at 16:53)</a>:</h4>
<p>Oh nice. No one posted that on Discord.</p>
<p>Ha, thanks. That clears it up perfeclty.</p>



<a name="231520759"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Meaning%20of%20lifetimes/near/231520759" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Meaning.20of.20lifetimes.html#231520759">(Mar 23 2021 at 18:35)</a>:</h4>
<p><span class="user-mention silent" data-user-id="399737">Christian Mazakas</span> <a href="#narrow/stream/122651-general/topic/Meaning.20of.20lifetimes/near/231503736">said</a>:</p>
<blockquote>
<p>What does it look like to create that kind of reference?</p>
<div class="codehilite"><pre><span></span><code>let v = 1337;
let x = &amp;v;
// x is `&amp;&#39;a i32` where &#39;a = full lifetime of `v`
</code></pre></div>
<p>How do we create a reference with a shorter lifetime?</p>
</blockquote>
<p>I don't understand that question very well (and thus the answer), is your intention to get a maximally-long borrow or on the contrary get a short borrow? The idea is that the borrows will "always be as short as possible", is one way to put, so getting a short borrow is trivial (it basically happens all the time), and the challenging one is making a borrow that is necessarily maximal. This one is tricky because you need to make sure any shorter borrow would be impossible to make.<br>
In practice, this is only achieved with a lifetime-infected type that implements <code>Drop</code> and by calling a method that borrows it for the same lifetime as its interior one:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[derive(Default)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">MaximallyBorrowable</span><span class="o">&lt;'</span><span class="na">slf</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="sd">/// Lifetime parameters needs to be invariant</span>
<span class="w">    </span><span class="sd">/// for the `.borrow_maximally()` to work.</span>
<span class="w">    </span><span class="n">_invariant_lifetime</span>: ::<span class="n">core</span>::<span class="n">marker</span>::<span class="n">PhantomData</span><span class="o">&lt;</span><span class="k">fn</span><span class="p">(</span><span class="o">&amp;</span><span class="p">())</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="o">&amp;'</span><span class="na">slf</span><span class="w"> </span><span class="p">()</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="w"> </span><span class="nb">Drop</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">MaximallyBorrowable</span><span class="o">&lt;'</span><span class="nb">_</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">drop</span><span class="w"> </span><span class="p">(</span><span class="bp">self</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="nb">_</span> <span class="nc">mut</span><span class="w"> </span><span class="bp">Self</span><span class="p">)</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="o">&lt;'</span><span class="na">slf</span><span class="o">&gt;</span><span class="w"> </span><span class="n">MaximallyBorrowable</span><span class="o">&lt;'</span><span class="na">slf</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">borrow_maximally</span><span class="w"> </span><span class="p">(</span><span class="bp">self</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">slf</span> <span class="nc">MaximallyBorrowable</span><span class="o">&lt;'</span><span class="na">slf</span><span class="o">&gt;</span><span class="p">)</span><span class="w"></span>
<span class="w">      </span>-&gt; <span class="kp">&amp;</span><span class="o">'</span><span class="na">slf</span> <span class="nc">MaximallyBorrowable</span><span class="o">&lt;'</span><span class="na">slf</span><span class="o">&gt;</span><span class="w"></span>
<span class="w">    </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">self</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="k">fn</span> <span class="nf">borrow_maximally_mut</span><span class="w"> </span><span class="p">(</span><span class="bp">self</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">slf</span> <span class="nc">mut</span><span class="w"> </span><span class="n">MaximallyBorrowable</span><span class="o">&lt;'</span><span class="na">slf</span><span class="o">&gt;</span><span class="p">)</span><span class="w"></span>
<span class="w">      </span>-&gt; <span class="kp">&amp;</span><span class="o">'</span><span class="na">slf</span> <span class="nc">mut</span><span class="w"> </span><span class="n">MaximallyBorrowable</span><span class="o">&lt;'</span><span class="na">slf</span><span class="o">&gt;</span><span class="w"></span>
<span class="w">    </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">self</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="w"> </span><span class="p">()</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">MaximallyBorrowable</span>::<span class="n">default</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">_maximal_borrow</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">borrow_maximally_mut</span><span class="p">();</span><span class="w"></span>
<span class="w">        </span><span class="cm">/* From now on `x` will remain `&amp;mut` borrowed, making `x` unusable */</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">x</span><span class="p">;</span><span class="w"> </span><span class="c1">// Error.</span>


<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">MaximallyBorrowable</span>::<span class="n">default</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">_maximal_borrow</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">borrow_maximally</span><span class="p">();</span><span class="w"></span>
<span class="w">        </span><span class="cm">/* From now on `x` will remain `&amp;` borrowed, making `x` only be</span>
<span class="cm">         * usable through _shared_ references. */</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">x</span><span class="p">;</span><span class="w"> </span><span class="c1">// OK</span>
<span class="w">    </span><span class="nb">drop</span><span class="p">(</span><span class="n">x</span><span class="p">);</span><span class="w"> </span><span class="c1">// Error.</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<ul>
<li><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=80d6c39da351e275288c0fb4db55dd42">Playground</a></li>
</ul>



<a name="231753449"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Meaning%20of%20lifetimes/near/231753449" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> csmoe <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Meaning.20of.20lifetimes.html#231753449">(Mar 25 2021 at 06:29)</a>:</h4>
<p><span class="user-mention" data-user-id="232018">@Daniel Henry-Mantilla</span> Your maxborrow snippet can be compiled with <code>self</code> and anonymous lifetime <a href="https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018&amp;gist=d855235fafe537469cf92256f328df5e">https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018&amp;gist=d855235fafe537469cf92256f328df5e</a><br>
what's the difference here?</p>



<a name="231816334"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Meaning%20of%20lifetimes/near/231816334" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Meaning.20of.20lifetimes.html#231816334">(Mar 25 2021 at 14:59)</a>:</h4>
<p>The difference is that your code compiles, precisely because by having used an anonymous lifetime, the borrow is no longer maximal <span aria-label="big smile" class="emoji emoji-1f604" role="img" title="big smile">:big_smile:</span> <br>
The OP seemed interested in seeing the difference between a short-lived borrow, and a long-lived one, hence my forging this example that showcases how it is the function signature and not its implementation, which dictates how long the borrow is held (indeed your Playground and mine feature the same implementation of "just passing <code>self</code> through").</p>
<ul>
<li>(what the implementation can do is put some constraints on the possible signatures, mainly preventing signatures from being too loose; but it won't prevent a signature from being over-restrictive).</li>
</ul>
<p>This is an important example, because, as we can see, with some signatures we might get some code to compile, where other signatures may lead to overly restrictive APIs such as in my example, causing code using the API to fail to compile.</p>
<p>As I mentioned before, Rust will always try to make the borrows be held for as little time as possible, and it does so for a reason: the longer a borrow is held, the more it hinders what other code can do.<br>
So, in a way, the query for a "maximally long borrow" is actually one for "over-restrictive, and thus bad¹ code"</p>
<ul>
<li>¹except for some very niche cases, mainly involving <code>unsafe</code> code.</li>
</ul>
<p>And indeed, in "real-life code", one ought to write the function signatures as you did, <span class="user-mention" data-user-id="116773">@csmoe</span>, with as many anonymous lifetimes as possible, and never ever writing the nested borrows that use the same named lifetime, precisely to avoid coming up with unnecessarily long borrows <span aria-label="smile" class="emoji emoji-1f642" role="img" title="smile">:smile:</span></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>